package flc.ast.utils;

import android.os.AsyncTask;
import android.util.Log;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.SocketTimeoutException;
import java.util.List;

public class FileUploader {
    private static final String BOUNDARY_PREFIX = "----WebKitFormBoundary";
    private static final String LINE_END = "\r\n";
    private static final int CONNECT_TIMEOUT = 15000;
    private static final int READ_TIMEOUT = 30000;

    public static class MultiFileUploadTask extends AsyncTask<Object, Void, String> {
        @Override
        protected String doInBackground(Object... params) {
            String ip = (String) params[0];
            String port = (String) params[1];
            List<File> files = (List<File>) params[2];

            String boundary = BOUNDARY_PREFIX + System.currentTimeMillis();
            HttpURLConnection conn = null;

            try {
                URL url = new URL("http://" + ip + ":" + port);
                conn = (HttpURLConnection) url.openConnection();
                conn.setConnectTimeout(CONNECT_TIMEOUT);
                conn.setReadTimeout(READ_TIMEOUT);
                conn.setDoInput(true);
                conn.setDoOutput(true);
                conn.setUseCaches(false);
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Connection", "Keep-Alive");
                conn.setRequestProperty("Cache-Control", "no-cache");
                conn.setRequestProperty("Content-Type",
                        "multipart/form-data; boundary=" + boundary);

                try (DataOutputStream dos = new DataOutputStream(conn.getOutputStream())) {
                    for (File file : files) {
                        writeFilePart(dos, boundary, file);
                    }
                    dos.writeBytes("--" + boundary + "--" + LINE_END);
                }
                Log.e("TAG", readServerResponse(conn));

            } catch (SocketTimeoutException e) {
                Log.e("TAG", "Error: Connection timeout");
            } catch (IOException e) {
                Log.e("TAG", e.getMessage());
            } finally {
                if (conn != null) conn.disconnect();
            }
            return "";
        }

        private void writeFilePart(DataOutputStream dos, String boundary, File file)
                throws IOException {
            dos.writeBytes("--" + boundary + LINE_END);
            dos.writeBytes("Content-Disposition: form-data; name=\"files\"; filename=\"" +
                    file.getName() + "\"" + LINE_END);
            dos.writeBytes("Content-Type: application/octet-stream" + LINE_END);
            dos.writeBytes(LINE_END);

            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] buffer = new byte[Math.min(4096, (int) file.length())];
                int bytesRead;
                while ((bytesRead = fis.read(buffer)) != -1) {
                    dos.write(buffer, 0, bytesRead);
                }
            }
            dos.writeBytes(LINE_END);
        }

        private String readServerResponse(HttpURLConnection conn) throws IOException {
            StringBuilder response = new StringBuilder();
            try (BufferedReader in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()))) {
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
            }
            return response.toString();
        }
    }
}
